package me.luger.core.mvc.filter.access;

import me.luger.core.commom.util.HttpUtil;
import me.luger.core.commom.util.JsonUtil;
import me.luger.core.commom.util.LogUtil;
import me.luger.core.mvc.WebService;
import me.luger.core.mvc.log.access.AccessLogEntity;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.UUID;

/**
 * Created by a on 2017/7/7.
 */
public class AccessFilter extends OncePerRequestFilter {

    @Autowired
    private Environment env;


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        try{
            String uri = request.getRequestURI();
            List<String> allRequestUrls = WebService.getRequestUrlList();

            if (!allRequestUrls.contains(uri)) {
                chain.doFilter(request,response);
                return;
            }

            String domain = WebService.getProjectDomain();
            String serverName = request.getServerName();
            if(StringUtils.isNotBlank(serverName) && serverName.endsWith(domain)){
                response.setHeader("Access-Control-Allow-Origin","*");
            }
            if(null != env){
                String basePath = env.getProperty("project.basePath");
                if(null != basePath){
                    request.setAttribute("base",basePath);
                }
            }

            AccessLogEntity accessLogEntity = this.preHandleLog(request,response);
            WebService.setAccessLogEntity(accessLogEntity);
            chain.doFilter(request,response);
            accessLogEntity.setEndTime(System.nanoTime());
            accessLogEntity.setExpend(accessLogEntity.getEndTime() - accessLogEntity.getBeginTime());
            LogUtil.accessLog(JsonUtil.toString(accessLogEntity));
            WebService.clean();
        }catch (Exception e){
            chain.doFilter(request,response);
            LogUtil.errorLog(e,"AccessFilter.doFilterInternal error");
        }
    }

    private AccessLogEntity preHandleLog(HttpServletRequest request, HttpServletResponse response){
        String reqId = UUID.randomUUID().toString();
        LogUtil.setLogId(reqId);

        AccessLogEntity logEntity = new AccessLogEntity();
        logEntity.setLogId(reqId);
        logEntity.setAccessDomain(request.getServerName());
        logEntity.setAccessIp(request.getRemoteAddr());
        logEntity.setBeginTime(System.nanoTime());
        logEntity.setGzip(HttpUtil.acceptsGzipEncoding(request));
        logEntity.setHttpMethod(request.getMethod());
        logEntity.setParams(request.getParameterMap());
        logEntity.setUrl(request.getRequestURI());
        logEntity.setUserIp(HttpUtil.getRemoteAddr(request));
        logEntity.setReferer(HttpUtil.getReferer(request));

        return logEntity;
    }
}
